package models

import (
	"github.com/jinzhu/gorm"
	"kop/libs/database"
	"kop/modules/configuration/configuration/attribute"
	"kop/modules/configuration/configuration/skill"
	"kop/modules/maid/configuration"
	"kop/modules/maid/entity"
	"kop/pb"
)

//
//func GetFriendMaidIDs(roleID int32) []int32 {
//
//	var data []entity.Maid
//	if err := database.DB.Find(&data, "role_id = ? AND is_friend = true", roleID).Error; err != nil {
//		panic(err)
//	}
//
//	var res []int32
//	for _, v := range data {
//		res = append(res, v.MaidID)
//	}
//
//	return res
//}

func GetMaids(dB *gorm.DB, roleID int32) []*pb.Maid {

	var data []entity.Maid
	if err := dB.Find(&data, "role_id = ?", roleID).Error; err != nil {
		panic(err)
	}

	var maids = make([]*pb.Maid, 0, len(data))

	for _, maidEntity := range data {
		var maid = buildPbMaid(maidEntity)
		maids = append(maids, &maid)
	}

	if len(maids) == 0 {

		var maid = Create(roleID, 2001)
		maids = append(maids, &maid)
	}

	return maids
}

func FriendMaids(dB *gorm.DB, roleID int32) []*pb.Maid {

	var data []entity.Maid
	if err := dB.Find(&data, "role_id = ? AND is_friend = true", roleID).Error; err != nil {
		panic(err)
	}

	var maids = make([]*pb.Maid, 0, len(data))

	for _, maidEntity := range data {
		var maid = buildPbMaid(maidEntity)
		maids = append(maids, &maid)
	}

	if len(maids) == 0 {

		var maid = Create(roleID, 2001)
		maids = append(maids, &maid)
	}

	return maids
}

func GetMaid(dB *gorm.DB, roleID, maidID int32) pb.Maid {

	var maidConf, err = configuration.GetByMaidID(maidID)
	if err != nil {
		panic(err)
	}

	var maidEntity = baseMaid(roleID, maidConf)
	if err = dB.FirstOrCreate(&maidEntity).Error; err != nil {
		panic(err)
	}

	return buildPbMaid(maidEntity)
}

func CountByClass(dB *gorm.DB, roleID, class int32) int32 {

	var count int32
	if err := dB.Model(&entity.Maid{}).Where(entity.Maid{RoleID: roleID, Class: class}).Count(&count).Error; err != nil {
		panic(err)
	}

	return count
}

// 创建已结交的侍女
func Create(roleID, maidID int32) pb.Maid {

	var maidConf, err = configuration.GetByMaidID(maidID)
	if err != nil {
		panic(err)
	}

	var data = entity.Maid{RoleID: roleID, MaidID: maidID}
	err = database.DB.First(&data).Error

	if err == gorm.ErrRecordNotFound {

		data = baseMaid(roleID, maidConf)
		data.IsFriend = true
		err = database.DB.Create(&data).Error

	} else if err == nil {

		data = baseMaid(roleID, maidConf)
		data.IsFriend = true
		err = database.DB.Save(&data).Error
	}

	if err != nil {
		panic(err)
	}

	return buildPbMaid(data)
}

func Save(db *gorm.DB, maid *pb.Maid) {

	var maidEntity = entity.Maid{
		RoleID:      maid.RoleID,
		MaidID:      maid.MaidID,
		Class:       maid.Class,
		Skin:        maid.Skin,
		Intimacy:    maid.Intimacy,
		Charm:       maid.Charm,
		Date:        maid.Date,
		Exp:         maid.Exp,
		Skill1Level: maid.Skills[0].Level,
		Skill2Level: maid.Skills[1].Level,
		Skill3Level: maid.Skills[2].Level,
		Skill4Level: maid.Skills[3].Level,
		Skill5Level: maid.Skills[4].Level,
		Skill6Level: maid.Skills[5].Level,
		Skill7Level: maid.Skills[6].Level,
		IsFriend:    maid.IsFriend,
	}

	if err := db.Save(&maidEntity).Error; err != nil {
		panic(err)
	}

	*maid = buildPbMaid(maidEntity)
	return
}

func buildPbMaid(maidEntity entity.Maid) pb.Maid {

	var maid = pb.Maid{
		RoleID:   maidEntity.RoleID,
		MaidID:   maidEntity.MaidID,
		Class:    maidEntity.Class,
		Skin:     maidEntity.Skin,
		Intimacy: maidEntity.Intimacy,
		Charm:    maidEntity.Charm,
		Date:     maidEntity.Date,
		Exp:      maidEntity.Exp,
		IsFriend: maidEntity.IsFriend,
	}

	var maidConf, err = configuration.GetByMaidID(maid.MaidID)
	if err != nil {
		panic(err)
	}

	// 爵位表
	classConf, err := configuration.GetByMaidClass(maidEntity.Class)
	if err != nil {
		panic(err)
	}

	// 基础属性读属性表的值
	attrConf, err := attribute.GetByAttributeID(classConf.AttributeID)
	if err != nil {
		panic(err)
	}

	maid.Attribute = &pb.Attribute{INT: 0, COR: 0, CHR: 0}

	// 爵位带的加成
	maid.AttributeRate = &pb.AttributeRate{
		INTRate: attrConf.INTRate,
		CORRate: attrConf.CORRate,
		CHRRate: attrConf.CHRRate,
	}

	maid.Skills = make([]*pb.MaidSkill, 0, len(maidConf.Skills))

	// 技能
	for k, skillID := range maidConf.Skills {

		var skillLevel int32 = 0
		switch k + 1 {
		case 1:
			skillLevel = maidEntity.Skill1Level
		case 2:
			skillLevel = maidEntity.Skill2Level
		case 3:
			skillLevel = maidEntity.Skill3Level
		case 4:
			skillLevel = maidEntity.Skill4Level
		case 5:
			skillLevel = maidEntity.Skill5Level
		case 6:
			skillLevel = maidEntity.Skill6Level
		case 7:
			skillLevel = maidEntity.Skill7Level
		}

		var skillConf, err = skill.GetByPassiveSkillID(skillID)
		if err != nil {
			panic(err)
		}

		attrConf, err = attribute.GetByAttributeID(skillConf.AttributeID + skillLevel)
		if err != nil {
			panic(err)
		}

		maid.Attribute.INT += attrConf.INT
		maid.Attribute.COR += attrConf.COR
		maid.Attribute.CHR += attrConf.CHR
		maid.AttributeRate.INTRate += attrConf.INTRate
		maid.AttributeRate.CORRate += attrConf.CORRate
		maid.AttributeRate.CHRRate += attrConf.CHRRate

		maid.Skills = append(maid.Skills, &pb.MaidSkill{
			SkillID: skillConf.SkillID,
			Level:   skillLevel,
			Value:   0,
			ExpCost: attrConf.ExpCost,
			Attribute: &pb.Attribute{
				INT: attrConf.INT,
				COR: attrConf.COR,
				CHR: attrConf.CHR,
			},
			AttributeRate: &pb.AttributeRate{
				INTRate: attrConf.INTRate,
				CORRate: attrConf.CORRate,
				CHRRate: attrConf.CHRRate,
			},
		})
	}

	return maid
}

func baseMaid(roleID int32, maidConf configuration.MaidConfig) entity.Maid {

	return entity.Maid{
		RoleID:      roleID,
		MaidID:      maidConf.MaidID,
		Intimacy:    maidConf.DefaultIntimacy,
		Charm:       maidConf.DefaultCharm,
		Skill1Level: 1,
		Skill2Level: 1,
		Skill3Level: 1,
		Skill4Level: 1,
		Skill5Level: 1,
		Skill6Level: 1,
		Skill7Level: 1,
	}
}
